﻿using System;
using System.Xml;

namespace Eff.Data
{

    /// <summary>
    /// xml帮助类
    /// </summary>
    [Obsolete("请直接使用XElement(linqtoxml)来操作xml")]
    public class XmlHelper
    {
        private readonly XmlDocument _xmlDoc;
        private XmlNodeList _nodes;
        private int _currentIndex;

        /// <summary>
        /// 
        /// </summary>
        public XmlNode Node
        {
            get
            {
                return _xmlDoc.DocumentElement;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public XmlHelper()
        {
            _xmlDoc = new XmlDocument();
        }



        /// <summary>
        /// 从文件取出xml.
        /// </summary>
        /// <param name="filename"></param>
        public void Load(string filename)
        {
            _xmlDoc.Load(filename);
        }

        /// <summary>
        /// 从字符串取出xml。
        /// </summary>
        /// <param name="xml"></param>
        public void LoadXml(string xml)
        {
            _xmlDoc.LoadXml(xml);
        }

        /// <summary>
        /// 找到特定的节点值
        /// </summary>
        /// <param name="name">节点名</param>
        /// <param name="values">节点值，可以为null即不匹配节点值</param>
        /// <returns>返回值</returns>
        public string Find(string name, string values)
        {
            _currentIndex = 0;
            string xpath = "//" + name;
            if (!string.IsNullOrEmpty(values))
            {
                xpath += "[text()=\"" + values + "\"]";
            }
            _nodes = _xmlDoc.SelectNodes(xpath);
            return Next();
        }

        /// <summary>
        /// 找到特定的节点
        /// </summary>
        /// <param name="name">节点名</param>
        /// <returns>返回值</returns>
        public string Find(string name)
        {
            return Find(name, null);
        }

        /// <summary>
        /// 找到特定的节点
        /// </summary>
        /// <param name="name">节点名</param>
        /// <param name="values">节点值，可以为null即不匹配节点值</param>
        /// <returns>返回值</returns>
        public XmlHelper FindObject(string name, string values)
        {
            _currentIndex = 0;
            string xpath = "//" + name;
            if (!string.IsNullOrEmpty(values))
            {
                xpath += "[text()=\"" + values + "\"]";
            }
            _nodes = _xmlDoc.SelectNodes(xpath);
            return NextXmlObject();
        }
        /// <summary>
        /// 找到特定的节点
        /// </summary>
        /// <param name="name">节点名</param>
        /// <returns>返回值</returns>
        public XmlHelper FindObject(string name)
        {
            return FindObject(name, null);
        }

        /// <summary>
        /// 返回下一个节点值
        /// </summary>
        /// <returns>返回值</returns>
        public string Next()
        {
            if (_nodes == null)
                throw new XmlException("No more nodes");
            if (_nodes.Count - 1 < _currentIndex)
                return null;
            return _nodes[_currentIndex++].InnerXml;
        }

        /// <summary>
        /// 此次查询是否有子节点
        /// </summary>
        /// <returns></returns>
        public bool HasChild()
        {
            if (_nodes == null)
                throw new XmlException("No children.");
            if (_nodes.Count > 0)
                return _nodes[0].HasChildNodes;
            return false;
        }

        /// <summary>
        /// 查找个数
        /// </summary>
        public int Count
        {
            get
            {
                if (_nodes == null)
                    throw new XmlException("No node.");
                return _nodes.Count;
            }
        }

        /// <summary>
        /// 返回一个xml对象，可以进行二次查找
        /// </summary>
        /// <returns></returns>
        public XmlHelper NextXmlObject()
        {
            if (_nodes == null)
                throw new XmlException("No more nodes.");
            if (_nodes.Count - 1 < _currentIndex)
                return null;
            var parser = new XmlHelper();
            parser.LoadXml(_nodes[_currentIndex++].OuterXml);
            return parser;
        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="name"></param>
        /// <param name="values">null则只添加节点名</param>
        /// <returns></returns>
        public XmlNode AddNode(XmlNode node, string name, string values)
        {
            if (node == null || name == null)
                return null;
            XmlNode cn = _xmlDoc.CreateNode(XmlNodeType.Element, name, "");
            node.AppendChild(cn);
            if (!string.IsNullOrEmpty(values))
            {
                XmlNode tn = _xmlDoc.CreateTextNode(values);
                cn.AppendChild(tn);
            }
            return cn;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="node"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        public void AddAttribute(XmlNode node, string name, string value)
        {
            if (node == null || name == null)
                return;
            XmlAttribute attr = _xmlDoc.CreateAttribute(name);
            attr.Value = value;
            if (node.Attributes != null) node.Attributes.Append(attr);
        }

        /// <summary>
        /// 添加根节点
        /// </summary>
        /// <param name="name"></param>
        /// <param name="encode"></param>
        /// <returns></returns>
        public XmlNode AddRoot(string name, string encode)
        {
            string xml = "<?xml version=\"1.0\" encoding=\"" + encode + "\" ?>";
            xml += "<" + name + "></" + name + ">";
            _xmlDoc.LoadXml(xml);
            return _xmlDoc.DocumentElement;
        }

        /// <summary>
        /// 输出成字符串
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return _xmlDoc.OuterXml;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string GetAttributeValue(string name)
        {
            XmlNode root = _xmlDoc.DocumentElement;
            if (root == null) return null;
            if (root.Attributes == null || root.Attributes.Count < 1)
                return null;

            XmlAttribute attr = root.Attributes[name];
            if (attr == null)
                return null;
            return attr.Value;

        }
    }
}
